package com.xavier.dong.nacos.grpc.client.interceptor;

import com.xavier.dong.nacos.grpc.client.config.GlobalInterceptorConfiguration;
import io.grpc.*;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.interceptor.GrpcGlobalClientInterceptor;

import java.util.UUID;

/**
 * 日志grpc拦截器,用来打印请求与响应日志
 * <p>
 * Example {@link ClientInterceptor} that logs all called methods in INFO log level, also request and response messages,
 * headers, trailers and interaction status in DEBUG log level. In this example it is added to Spring's application
 * context via {@link GlobalInterceptorConfiguration}, but is also possible to directly annotate this class with
 * {@link GrpcGlobalClientInterceptor}.
 *
 * @author <a href="mailto:xing.dong@sha.ontime-express.com">Xavier Dong</a>
 * @date
 */
//@GrpcGlobalServerInterceptor
@Slf4j
public class LogGrpcInterceptor implements ClientInterceptor {

    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(final MethodDescriptor<ReqT, RespT> method, final CallOptions callOptions, final Channel next) {

        return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {

            /**
             * 请求id
             */
            String requestId = UUID.randomUUID().toString();

            @Override
            public void sendMessage(ReqT message) {
                log.info("interceptCall sending message, method:{} requestId: {} message:{} ", method.getFullMethodName(), requestId, message.toString());
                super.sendMessage(message);
            }

            @Override
            public void start(Listener<RespT> responseListener, Metadata headers) {
                super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) {
                    @Override
                    public void onMessage(RespT message) {
                        log.info("interceptCall response requestId: {} message:{} ", requestId, message.toString());
                        super.onMessage(message);
                    }

                    @Override
                    public void onHeaders(Metadata headers) {
                        log.info("interceptCall gRPC headers:{} ", headers);
                        super.onHeaders(headers);
                    }

                    @Override
                    public void onClose(Status status, Metadata trailers) {
                        log.info("Interaction ends with status: {}", status);
                        log.info("Trailers: {}", trailers);
                        super.onClose(status, trailers);
                    }
                }, headers);
            }
        };
    }


}